<?php
defined('IN_HRLOO') or exit('Access Denied');
class fx_utl {
	
	/**
	 * 加密 3DES
	 * @param string $plaintext 要加密的明文
	 * @param string $key 加密KEY
	 * @return string 结果为字符串
	 */
	public static function encrypt($plaintext, $key) {
		//MCRYPT_TRIPLEDES; // 加密方法
		$iv = mcrypt_create_iv ( mcrypt_get_iv_size ( MCRYPT_TRIPLEDES, MCRYPT_MODE_ECB ), MCRYPT_RAND ); // 初始化向量来增加安全性
		$encrypted_string = mcrypt_encrypt ( MCRYPT_TRIPLEDES, $key, $plaintext, MCRYPT_MODE_ECB, $iv ); // 开始加密
		return $encrypted_string;
	}
	
	/**
	 * 解密 3DES
	 * @param string $ciphertext 密文
	 * @param string $key 解密KEY
	 * @return string 
	 */
	public static function decrypt($ciphertext, $key) {
		//MCRYPT_TRIPLEDES; // 加密方法
		$iv = mcrypt_create_iv ( mcrypt_get_iv_size ( MCRYPT_TRIPLEDES, MCRYPT_MODE_ECB ), MCRYPT_RAND );
		$decrypted_string = mcrypt_decrypt ( MCRYPT_TRIPLEDES, $key, $ciphertext, MCRYPT_MODE_ECB, $iv );
		return rtrim($decrypted_string,"\0\4"); 
	}
	
	/**
	 * 加密，加盐4位，base64编码
	 * @param unknown_type $plaintext
	 * @param unknown_type $key
	 */
	public static function encrypt_salt_base64($plaintext, $key) {
		$salt = self::random_str(4);
		$key = $key.$salt;
		$encrypted_string = self::encrypt($plaintext,$key);
		$encrypted_string = base64_encode($encrypted_string);
		$encrypted_string = $salt.$encrypted_string;
		return $encrypted_string;
	}
	
	/**
	 * 解密，加盐4位，base64编码
	 * @param unknown_type $ciphertext
	 * @param unknown_type $key
	 */
	public static function decrypt_salt_base64($ciphertext, $key) {
		$salt = substr($ciphertext,0,4);
		$ciphertext = substr($ciphertext,4);
		$ciphertext = base64_decode($ciphertext);
		return self::decrypt($ciphertext,$key.$salt);
	}
	
	/**
	 * 给引号加斜杠,如果是数组则KEY和VAL都加
	 * @param string|array $string
	 * @param int $force
	 * @return string|array
	 */
	public static function addslashes($string, $force = 1) {
		if(is_array($string)) {
			$keys = array_keys($string);
			foreach($keys as $key) {
				$val = $string[$key];
				unset($string[$key]);
				$string[addslashes($key)] = self::addslashes($val, $force);
			}
		} else {
			$string = addslashes($string);
		}
		return $string;
	}
	
	/**
	 * 设置加密Cookie信息
	 * @param string $name 名称
	 * @param string $value 值
	 * @param int $expire 过期时间 默认 关闭浏览器后即失效
	 * @param string $path 路径 默认 /
	 * @param string $domain 域  默认hrloo.com
	 */
	public static function savecookie($name, $value = null, $expire = 0, $path = "/", $domain =HAUTH_COOKIE_DOMAIN ) {
		if ($value) {
			$value = self::encrypt_salt_base64($value, HENCRYPT_KEY);
		}
		
		setcookie($name, $value, $expire, $path, $domain);
	}
	
	/**
	 * 获取加密Cookie原始信息
	 * @param string $name 名称
	 * @return string
	 */
	public static function getcookie($name) {
		$value = $_COOKIE[$name];
		if ($value) {
			$value = self::decrypt_salt_base64($value, HENCRYPT_KEY);
		}
		
		return $value;
	}
	
	/**
	 * 去斜杠
	 * @param string|array $string
	 * @return string|array
	 */
	public static function stripslashes($string) {
		if(empty($string)) return $string;
		if(is_array($string)) {
			foreach($string as $key => $val) {
				$string[$key] = self::stripslashes($val);
			}
		} else {
			$string = stripslashes($string);
		}
		return $string;
	}
	
	/**
	 * 生成一个指定长度字符为a-Z0-9的随机串
	 * @param int $length
	 * @return string
	 */
	public static function random_str($length) {
		$hash = '';
		$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
		$max = strlen($chars) - 1;
		PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
		for($i = 0; $i < $length; $i++) {
			$hash .= $chars[mt_rand(0, $max)];
		}
		return $hash;
	}
	
	/**
	 * 对密码进行HASH，加SALT
	 * @param string $password
	 * @return array('password'=>password,'salt'=>salt)
	 */
	public static function hash_pwd($password,$salt_len=6){
		$salt = self::random_str($salt_len);
		$pass = md5(md5($password).$salt);
		return array('password'=>$pass,'salt'=>$salt);
	}
	
	/**
	 * 对密码进行HASH，加SALT
	 * @param string $password
	 * @param string $salt
	 * @return string
	 */
	public static function hash_pwd_bysalt($password,$salt){
		return md5(md5($password).$salt);
	}
	
	/**
	 * 将数组拼成URL参数，使用http_build_query?
	 * @param unknown_type $arr
	 * @param unknown_type $glue
	 * @param unknown_type $spliter
	 */
	public static function join_kv($arr,$glue,$spliter='=',$encode=true){
		//todo: liaozc 是否直接使用http_build_query?
		$ret = array();
		foreach($arr as $k=>$v){
			if($encode){
				$ret[] = "$k$spliter".urlencode($v);
			}else{
				$ret[] = "$k$spliter$v";
			}
		}
		return join($glue,$ret);
	}
	
	/**
	 * 存取缓存，与数据库
	 * 首先从缓存中读取，如果没有则从数据库读取，然后设置到缓存中
	 * @param fx_cache_memcached $cache
	 * @param string $ckey
	 * @param fx_da_mysql $db
	 * @param string $sql
	 * @param array $param
	 */
	public static function cache_or_sql($cache,$key,$db,$sql,$param,$ttl=0){
		$ret = $cache->get($key); 
		if(!$ret){ //todo: liaozc maybe a bug NULL,0,'' ????
			$ret = $db->fetch_all($sql,$param);
			$cache->set($key,$ret,$ttl);
		}
		return $ret;
	}
	
	/**
	 * 将URL和参数合并,如果中带有？则&.$paramstr,否则?.$paramstr
	 * @param string $url
	 * @param string $paramstr
	 */
	public static function combine_url_param($url,$paramstr){
		if(strpos($url, '?')===false){
			return $url.'?'.$paramstr;
		}
		return $url.'&'.$paramstr;
	}
	
/*===========================================
 * 较验相关的
=========================================== */
	
	/**
	 * 检查密码长度是否符合规定
	 *
	 * @param STRING $password
	 * @return 	TRUE or FALSE
	 */
	public static function is_password($password) {
		$strlen = strlen($password);
		if($strlen >= 6 && $strlen <= 20) return true;
		return false;
	}
	
	/**
	 * 检测输入中是否含有错误字符
	 *
	 * @param char $string 要检查的字符串名称
	 * @return TRUE or FALSE
	 */
	public static function is_badword($string) {
		$badwords = array("\\",'&',' ',"'",'"','/','*',',','<','>',"\r","\t","\n","#");
		foreach($badwords as $value){
			if(strpos($string, $value) !== FALSE) {
				return TRUE;
			}
		}
		return FALSE;
	}
	
	/**
	 * 检查用户名是否符合规定
	 *
	 * @param STRING $username 要检查的用户名
	 * @return 	TRUE or FALSE
	 */
	public static function is_username($username) {
		$strlen = strlen($username);
		if(self::is_badword($username) || !preg_match("/^[a-zA-Z0-9_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+$/", $username)){
			return false;
		} elseif ( 20 < $strlen || $strlen < 2 ) {
			return false;
		}
		return true;
	}
	
	/**
	 * 比较两个时间的大小 格式 HH:MM[:SS]
	 * t1<t2 -1; t1=t2 0; t1>t2 1
	 * @param string $t1 
	 * @param string $t2
	 * @return int
	 */
	public static function comp_time($t1,$t2){
		$t1 = strtotime('1970-02-01 '.$t1);
		$t2 = strtotime('1970-02-01 '.$t2);
		return $t1==$t2 ? 0 : ($t1<$t2 ? -1 : 1);
	}
	
	/**
	 * 获取Uinx时间戳的日期部分的时间戳，即yyyy-mm-dd 00:00:00
	 * @param int|string $datetime Uinx时间戳
	 * @param bool $ret_str 是否返回字符串
	 */
	public static function get_datepart($datetime,$ret_str=false){
		if(!is_numeric($datetime)){
			$datetime = strtotime($datetime);
		}
		$td = date('Y-m-d',$datetime);
		if($ret_str) return $td;
		return strtotime($td);
	}
	
	/**
	 * 日期加上时间 2012-01-01 12:01:01 + 7:30[:xx] =??? 
	 * @param string:int $int
	 * @param string $time_str
	 * @return int Unixtimestamp
	 */
	public static function date_add($datetime,$time_str){
		if(!is_numeric($datetime)){
			$datetime = strtotime($datetime);
		}
		$t_arr = explode(':',$time_str);
		$fact = 3600;
		$inc = 0;
		foreach($t_arr as $v){
			$inc += $v * $fact;
			$fact = $fact/60;
		}
		return $datetime + $inc;
	}
	
	/**
	 * 日期减去时间 2012-01-01 12:01:01 - 7:30[:xx] =???
	 * @param string|int $int
	 * @param string $time_str
	 * @return int Unixtimestamp
	 */
	public static function date_sub($datetime,$time_str){
		if(is_string($datetime)) $datetime = strtotime($datetime);
		$t_arr = explode(':',$time_str);
		$fact = 3600;
		$dec = 0;
		foreach($t_arr as $v){
			$dec += $v * $fact;
			$fact = $fact/60;
		}
		return $datetime - $dec;
	}
	
	/**
	 * 获取指定月份的第1天及最后1天
	 * @param int|string|unixtimestamp $month 0表未当前月
	 * @return array(0,1) unixtimestamp first,last
	 */
	public static function month_first_last_date($month){
		if(!$month) $month = time();
		if(is_string($month)) $month = strtotime($month);
		$tmp = date('Y-m',$month);
		$ret[] = strtotime($tmp.'-01');
		$ret[] = strtotime($tmp.'-'.date('t',$month));
		return $ret;
	}
	
	/**
	 * 获取指定时间的下月第一天
	 * @param int $monthtime
	 * @throws fx_validexp
	 * @return number
	 */
	public static function month_next_first_date($monthtime){
		if(!$monthtime){
			$monthtime = time();
		}
		if(is_string($monthtime)){
			throw new fx_validexp('请输入unixtime格式');
		}
		$month = idate('m', $monthtime);
		if($month == 12){
			return strtotime((idate('Y', $monthtime) + 1).'-01-01');
		}
		else {
			return strtotime(date('Y'.'-'.( $month + 1 ).'-01', $monthtime));
		}
	}
	
	/**
	 * 获取指定时间的上月第一天
	 * @param int $monthtime
	 * @throws fx_validexp
	 * @return number
	 */
	public static function month_pre_first_date($monthtime){
		if(!$monthtime){
			$monthtime = time();
		}
		if(is_string($monthtime)){
			throw new fx_validexp('请输入unixtime格式');
		}
		$month = idate('m', $monthtime);
		if($month == 1){
			return strtotime((idate('Y', $monthtime) - 1).'-12-01');
		}
		else {
			return strtotime(date('Y'.'-'.( $month - 1 ).'-01', $monthtime));
		}
	}
	
	/**
	 * 获取指定时间的第一天
	 * @param int $monthtime
	 * @throws fx_validexp
	 * @return number
	 */
	public static function month_first_date($monthtime){
		if(!$monthtime){
			$monthtime = time();
		}
		if(is_string($monthtime)){
			throw new fx_validexp('请输入unixtime格式');
		}
		return strtotime(date('Y-m'.'-01', $monthtime));
	}
	/**
	 * 转化 \ 为 /
	 *
	 * @param	string	$path	路径
	 * @return	string	路径
	 */
	public static function dir_path($path) {
		$path = str_replace('\\', '/', $path);
		if(substr($path, -1) != '/') $path = $path.'/';
		return $path;
	}
	/**
	 * 创建目录
	 *
	 * @param	string	$path	路径
	 * @param	string	$mode	属性
	 * @return	string	如果已经存在则返回true，否则为flase
	 */
	public static function dir_create($path, $mode = 0777) {
		if(is_dir($path)) return TRUE;
		$ftp_enable = 0;
		$path =self::dir_path($path);
		$temp = explode('/', $path);
		$cur_dir = '';
		$max = count($temp) - 1;
		for($i=0; $i<$max; $i++) {
			$cur_dir .= $temp[$i].'/';
			if (@is_dir($cur_dir)) continue;
			@mkdir($cur_dir, 0777,true);
			@chmod($cur_dir, 0777);
		}
		return is_dir($path);
	}
	
	/**
	 * 防跨站脚本,处理script，iframe，frame，]]>
	 * @param string $str
	 * @return array
	 */
	public static function strip_script($str) {
		$str = preg_replace('/\<([\/]?)script([^\>]*?)\>/si', '&lt;\\1script\\2&gt;', $str);
		$str = preg_replace('/\<([\/]?)iframe([^\>]*?)\>/si', '&lt;\\1iframe\\2&gt;', $str);
		$str = preg_replace('/\<([\/]?)frame([^\>]*?)\>/si', '&lt;\\1frame\\2&gt;', $str);
		$str = preg_replace('/]]\>/si', ']] >', $str);
		return $str;
	}
	
	/**
	 * 防跨站脚本,处理script，iframe，frame，]]> 为空
	 * @param unknown_type $str
	 * @return mixed
	 */
	public static function strip_script_replace($str){
		$str = preg_replace("'<script(.*?)<\/script>'is", '', $str);
		$str = preg_replace('/\<([\/]?)iframe([^\>]*?)\>/si', '', $str);
		$str = preg_replace('/\<([\/]?)frame([^\>]*?)\>/si', '', $str);
		$str = preg_replace('/]]\>/si', '', $str);
		return $str;
	}
	
	/**
	 * 移除HTML代码中的表单元素
	 * @param string $html HTML代码
	 */
	public static function strip_form($html) {
		$html = preg_replace('/\<([\/]?)form([^\>]*?)\>/si', '&lt;\\1form\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)input([^\>]*?)\>/si', '&lt;\\1input\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)textarea([^\>]*?)\>/si', '&lt;\\1textarea\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)label([^\>]*?)\>/si', '&lt;\\1label\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)fieldset([^\>]*?)\>/si', '&lt;\\1fieldset\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)legend([^\>]*?)\>/si', '&lt;\\1legend\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)select([^\>]*?)\>/si', '&lt;\\1select\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)optgroup([^\>]*?)\>/si', '&lt;\\1optgroup\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)option([^\>]*?)\>/si', '&lt;\\1option\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)button([^\>]*?)\>/si', '&lt;\\1button\\2&gt;', $html);
		return $html;
	}
	/**
	 * 移除HTML代码中的script，iframe及form表单元素。
	 * @param string $html
	 * @return string
	 */
	public static function strip_dangertag($html){
		$html = self::strip_script($html);
		$html = self::strip_form($html);
		$html = self::strip_style($html);
		return $html;
	}
	/**
	 * 移除 html编辑器的中script,iframe,style,form等元素
	 * @param string $html
	 * @param array $property  需要移除的特有标签属性，默认 class,id,name
	 * @param array $tag  需要移除的特有标签，默认 dd,dt,dl
	 */
	public static function strip_htmleditor($html,$property=array("class","id","name"),$tag=array("dd","dt","dl")){		
		$html = self::strip_script($html);
		$html = self::strip_form($html);
		$html = self::strip_style($html);
		if($property){			
			foreach ($property as $p)
			{
				$html =preg_replace('/'.$p.'="[^"]+"/si',"",$html);
				$html =preg_replace('/'.$p.'=\'[^\']+\'/si',"",$html);
			}
		}
		if($tag){
			foreach ($tag as $v)
			{
				$html = preg_replace('/\<([\/]?)'.$v.'([^\>]*?)\>/si','',$html);
			}
		}
		return $html;						
	}
	/**
	 * 移除HTML代码中的样式
	 * @param string $html HTML代码
	 */
	public static function strip_style($html) {
		$html = preg_replace('/\<([\/]?)link([^\>]*?)\>/si', '&lt;\\1link\\2&gt;', $html);
		$html = preg_replace('/\<([\/]?)style([^\>]*?)\>/si', '&lt;\\1style\\2&gt;', $html);
		return $html;
	}
	
	/**
	 * 取得文件扩展
	 *
	 * @param $filename 文件名
	 * @return 扩展名
	 */
	public static function fileext($filename) {
		return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
	}
	/**
	 * 生成GUID串
	 */
	public static function create_guid() {
		$charid = strtoupper(md5(uniqid(mt_rand(), true)));
		$uuid =substr($charid, 0, 8)
		.substr($charid, 8, 4)
		.substr($charid,12, 4)
		.substr($charid,16, 4)
		.substr($charid,20,12);
		return strtolower($uuid);
	}	
	
	/**
	 * 提取二维数组中的列
	 * @param array $arr
	 * @param string $column
	 * @return array
	 */
	public static function array_column($arr,$column){
		foreach ($arr as $k => $v){
			$ret[$k] = $v[$column]	;
		}
		return $ret;
	}
	
	/**
	 * 提取二维数组中的列 到一维数组中
	 * @param array $arr
	 * @param string $column
	 * @return array 一维数组
	 */
	public static function array_2_array1($arr,$column){
		$ret = array();
		foreach ($arr as $row){
			$ret[] = $row[$column];
		}
		return $ret;
	}
	
	/**
	 * 截字，后面带...
	 * @param unknown_type $string
	 * @param unknown_type $sublen
	 * @param unknown_type $dot
	 * @param unknown_type $start
	 * @param unknown_type $code
	 * @return Ambigous <string, unknown, unknown_type>
	 */
	public static function str_cut($string, $sublen,$dot='...', $start = 0, $code = 'UTF-8'){
		return self::hstr_cut($string,$sublen, $dot, $start, $code);
	}
	
	/**
	 * 截字，后面带...
	 * @param unknown_type $string
	 * @param unknown_type $sublen
	 * @param unknown_type $dot
	 * @param unknown_type $start
	 * @param unknown_type $code
	 * @return string|unknown
	 */
	public static function hstr_cut($string, $sublen,$dot='...', $start = 0, $code = 'UTF-8')
	{
		if($code == 'UTF-8')
		{
			$pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";
			preg_match_all($pa, $string, $t_string);
	
			if(count($t_string[0]) - $start > $sublen) return join('', array_slice($t_string[0], $start, $sublen)).$dot;
			return join('', array_slice($t_string[0], $start, $sublen));
		}
		else
		{
			$start = $start*2;
			$sublen = $sublen*2;
			$strlen = strlen($string);
			$tmpstr = '';
	
			for($i=0; $i< $strlen; $i++)
			{
				if($i>=$start && $i< ($start+$sublen))
				{
					if(ord(substr($string, $i, 1))>129)
					{
						$tmpstr.= substr($string, $i, 2);
					}
					else
					{
						$tmpstr.= substr($string, $i, 1);
					}
				}
				if(ord(substr($string, $i, 1))>129) $i++;
			}
			if(strlen($tmpstr)< $strlen ) $tmpstr.= $dot;
			return $tmpstr;
		}
	}
	
	/**
	 * 获取IP地址
	 * @param $ret_int 是否返回整型
	 * @return string|int
	 */
	public static function hip($ret_int=false) {
	    if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
	        $ip = getenv('HTTP_CLIENT_IP');
	    } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
	        $ip = getenv('HTTP_X_FORWARDED_FOR');
	    } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
	        $ip = getenv('REMOTE_ADDR');
	    } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
	        $ip = $_SERVER['REMOTE_ADDR'];
	    }
	    $ip = preg_match('/[\d\.]{7,15}/', $ip, $matches) ? $matches [0] : '';
	    if($ret_int) $ip = ip2long($ip);
	    return $ip;
	}
	
	/**
	 * 判断是不是邮箱
	 * @param string $str
	 * @return false如果不是邮箱
	 */
	public static function is_email($str){
		return filter_var($str,FILTER_VALIDATE_EMAIL);
	}

	
	/**
	 * Hash密码,md5(md5($password),$salt)
	 * @param string $password
	 * @param string $salt
	 * @return string
	 */
	public static function password($password,$salt){
		return md5(md5($password).$salt);
	}
	
	/**
	 * 计算中英文混排的字符长度，中文字符算2字节
	 * @param string $str
	 * @return number
	 */
	public static function strlen_utf8($str){
		$i = 0;
		$count = 0;
		$len = strlen ($str);
		while ($i < $len) {
			$chr = ord ($str[$i]);
			$i++;
			if($chr & 0x80) {
				$count++;
				$count++;
				$chr <<= 1;
				while ($chr & 0x80) {
					$i++;
					$chr <<= 1;
				}
			}else{
				$count++;
			}
			if($i >= $len) break;
		}
		return $count;
	}
	
	/**
	 * 字符串的复杂度
	 * @param string $str
	 * @return 1,2,4,8   1数字，2大写，4小写，8特殊符号
	 */
	public static function str_consist($str){
		$str = ''.$str;
		$hasdigital = 0;
		$hascapital=0;
		$hasletter = 0;
		$hasspecialchar = 0;
		
		$i = 0;
		$len = strlen ($str);
		while ($i < $len) {
			$chr = ord ($str[$i]);
			if($chr>=48 && $chr <=57) $hasdigital=1;
			else if($chr>=65 && $chr <=90) $hascapital=2;
			else if($chr>=97 && $chr <=122) $hasletter=4;
			else $hasspecialchar=8;
			$i++;
		}
		return $hasdigital + $hascapital + $hasletter + $hasspecialchar;
	}
	
	/**
	 * 判断字符串是否是纯数字或字母，大小混合的不算纯字母
	 * @param string $str
	 */
	public static function str_is_pure_digitalorletter($str){
		$c = self::str_consist($str);
		$i += $c & 0x1;
		$i += ($c>>1) & 0x1;
		$i += ($c>>2) & 0x1;
		$i += ($c>>3) & 0x1;
		return $i < 2;
	}
	
	/**
	 * discuz的加密码方法（RC4）
	 * @param string $string
	 * @param string $operation
	 * @param string $key   discuz 的 authkey
	 * @param int $expiry
	 * @return string
	 */
	public static function dauthcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
		$ckey_length = 4;
		$key = md5($key);
		$keya = md5(substr($key, 0, 16));
		$keyb = md5(substr($key, 16, 16));
		$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
	
		$cryptkey = $keya.md5($keya.$keyc);
		$key_length = strlen($cryptkey);
	
		$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
		$string_length = strlen($string);
	
		$result = '';
		$box = range(0, 255);
	
		$rndkey = array();
		for($i = 0; $i <= 255; $i++) {
			$rndkey[$i] = ord($cryptkey[$i % $key_length]);
		}
	
		for($j = $i = 0; $i < 256; $i++) {
			$j = ($j + $box[$i] + $rndkey[$i]) % 256;
			$tmp = $box[$i];
			$box[$i] = $box[$j];
			$box[$j] = $tmp;
		}
	
		for($a = $j = $i = 0; $i < $string_length; $i++) {
			$a = ($a + 1) % 256;
			$j = ($j + $box[$a]) % 256;
			$tmp = $box[$a];
			$box[$a] = $box[$j];
			$box[$j] = $tmp;
			$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
		}
	
		if($operation == 'DECODE') {
			if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
				return substr($result, 26);
			} else {
				return '';
			}
		} else {
			return $keyc.str_replace('=', '', base64_encode($result));
		}
	
	}
	
	/**
	 * 判断一个字符串是不是有序的。
	 * @param string $str
	 * @return -1,0,1 -1升序，0乱序，1降序
	 */
	public static function is_ordered($str){
		if(!is_string($str)) $str = ''.$str;
		$len = strlen ($str);
		if($len < 2) return 0;
		$ord1 = ord($str[0]);
		$i = 1;
		$asc = true;
		$desc = true;
		
		while($i<$len){
			$ord2 = ord($str[$i]);
			$asc = $asc && (($ord1 + 1) == $ord2);
			$desc = $desc && (($ord1 - 1) == $ord2);
			$ord1 = $ord2;
			$i++;
		}
		
		if($asc) return -1;
		else if($desc) return 1;
		
		return 0;
	}
	
	
	/**
	 * 将字符串转换为数组
	 *
	 * @param	string	$data	字符串
	 * @return	array	返回数组格式，如果，data为空，则返回空数组
	 */
	public static function string2array($data) {
		$array=null;
		if ($data == '')
			return array();
		eval("\$array = $data;");
		return $array;
	}
	
	/**
	 * 将数组转换为字符串
	 *
	 * @param	array	$data		数组
	 * @return	string	返回字符串，如果，data为空，则返回空
	 */
	public static function array2string($data) {
		if ($data == '')
			return '';
		return var_export($data, TRUE);
	}

	/**
	 * 过滤数组，$array中元索值与$arr_filter相同的
	 * @param array $array
	 * @param array $arr_filter
	 * @return array
	 */
	public static function array_filter($array,$arr_filter){
		$ret = array();
		foreach($array as &$a){
			foreach($arr_filter as $k=>$v){
				$t = $a[$k] == $v;
				if(!$t) break; 
			}
			if($t) $ret[] = &$a;
			unset($a);
		}
		return $ret;
	}
	/**
	 * 将数组转换成指定的 key_value结构
	 * @param unknown_type $array
	 * @param unknown_type $fieldkey
	 * @param unknown_type $fieldvalue
	 */
	public static function array_kv($array,$fieldkey,$fieldvalue=null){
		$ret=array();
		foreach ($array as $v){
			if($fieldvalue){
				$ret[$v[$fieldkey]]=$v[$fieldvalue];
			}else{
				$ret[$v[$fieldkey]]=$v;
			}
		}
		return $ret;
		
	}
	/**
	 * 提取指定条数，
	 * @param array $array
	 * @param int $num
	 */
	public static function array_fetch($array,$num){
		$i=0;
		$list=array();
		foreach ($array as $k=>$v){
			$i++;
			if($i<=$num){
				$list[]=$array[$k];
			}else{
				break;
			}
		}
		return $list;
	}
	
	/**
	 * 生成HTML的摘要
	 * @param string $html
	 * @param int $len
	 * @param string $dot
	 */
	public static function html2desc($html,$len,$dot='...'){
		$html = strip_tags($html);
		if(mb_strlen($html,'utf-8')>$len){
			return mb_substr($html,0,$len).$dot;
		}
		return $html;
	}
	
	
	/**
	 * 获取自然周(这里是周一到周七)的开始，结束日期
	 * @param int $index 0当周,-n前n周 n后n周
	 * @param int $t 当前时间
	 */
	public static function week_start_end($index=0,$t=0){
		$ret = array();
		if(!$t){
			$t = time();
		}
		$date = fx_utl::get_datepart($t);
		
		$w = idate('w', $date);
		if($w == 0 ) $w = 7;
			
		$ret[0] = $date - 86400 * ($w - 1) + $index * 86400 * 7;
		$ret[1] = $date + 86400 * (7 - $w) + $index * 86400 * 7;
		return $ret;
	}

	public static function checkmobile() {
		$mobile = array();
		static $touchbrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',
					'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',
					'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',
					'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',
					'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',
					'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',
					'benq', 'haier', '^lct', '320x320', '240x320', '176x220');
		static $mobilebrowser_list =array('windows phone');
		static $wmlbrowser_list = array('cect', 'compal', 'ctl', 'lg', 'nec', 'tcl', 'alcatel', 'ericsson', 'bird', 'daxian', 'dbtel', 'eastcom',
				'pantech', 'dopod', 'philips', 'haier', 'konka', 'kejian', 'lenovo', 'benq', 'mot', 'soutec', 'nokia', 'sagem', 'sgh',
				'sed', 'capitel', 'panasonic', 'sonyericsson', 'sharp', 'amoi', 'panda', 'zte');

		$pad_list = array('pad', 'gt-p1000');

		$useragent = strtolower($_SERVER['HTTP_USER_AGENT']);

		if(self::hstrpos($useragent, $pad_list)) {
			return false;
		}
		if(($v = self::hstrpos($useragent, $mobilebrowser_list, true))){
			return '1';
		}
		if(($v = self::hstrpos($useragent, $touchbrowser_list, true))){
			return '2';
		}
		if(($v = self::hstrpos($useragent, $wmlbrowser_list))) {
			return '3'; //wml版
		}
		$brower = array('mozilla', 'chrome', 'safari', 'opera', 'm3gate', 'winwap', 'openwave', 'myop');
		if(self::hstrpos($useragent, $brower)) return false;

		return false;
	}

	public static function hstrpos($string, $arr, $returnvalue = false) {
		if(empty($string)) return false;
		foreach((array)$arr as $v) {
			if(strpos($string, $v) !== false) {
				$return = $returnvalue ? $v : true;
				return $return;
			}
		}
		return false;
	}
	
} 
